#include "monkey.h"
#include <QDebug>

Monkey::Monkey() { }

Monkey::Monkey(MonkeySide i_side)
{
    imageIndex = 0;
    int xCoord;
    if (i_side == LEFT) {
        image = LEFT_MONKEY_FRAMES.at(imageIndex);
        xCoord = MONKEY_DISTANCE_FROM_BORDER;
    } else {
        image = RIGHT_MONKEY_FRAMES.at(imageIndex);
        xCoord = WORLD_WIDTH - MONKEY_DISTANCE_FROM_BORDER - MONKEY_WIDTH;
    }

    rect = QRect(xCoord, MONKEY_LOWEST_POINT, MONKEY_WIDTH, MONKEY_HEIGHT);
    type = MONKEY;
    dir = UP;
    speed = MONKEY_CLIMBING_SPEED.at(_difficulty_) * dir;
    isMovable = false;
    isHitable = true;
    destroyLater = false;
    side = i_side;
    moveThisTime = true; // because the monkey position is only updated every 2nd timerhit

    // for AI
    targetId = -1;
    cocoTime = 0;
    setMaxLoadTime();
}

// updates the monkeys position
void Monkey::updatePosition()
{
    if (isHitable)
    {
        if (isMovable &&
                ((dir == UP && rect.y() > MONKEY_HEIGHEST_POINT) ||
                 (dir == DOWN && rect.y() < MONKEY_LOWEST_POINT)))
        {
            if (moveThisTime) {     // monkey only moved every 2nd frame when climbing
                nextImage();
                rect.translate(0, speed);
                mObs->movedInModel(objId, rect.x(), rect.y());
            }
            moveThisTime = !moveThisTime;
        }
    }
    else if (!isHitable)    // monkey is falling down b/c it was hit by a coconut earlier
    {
        if (rect.y() < MONKEY_LOWEST_POINT)
        {
            nextImage();
            rect.translate(0, MONKEY_FALLING_SPEED);
            mObs->movedInModel(objId, rect.x(), rect.y());
        }
        else
        {
            isHitable = true;
            imageIndex = 0;
            isMovable = false;
            moveThisTime = true;
            nextImage();
            mObs->setMonkeyToFalling(std::vector<PlayerType>{HOST,CLIENT}.at(objId), false);
        }
    }
}


void Monkey::nextImage()
{
    if (side == LEFT && isHitable)
    {
        imageIndex = (imageIndex + 1) % LEFT_MONKEY_FRAMES.size();
        image = LEFT_MONKEY_FRAMES.at(imageIndex);
    }
    else if (side == LEFT && !isHitable)
    {
        imageIndex = (imageIndex + 1) % LEFT_MONKEY_FALLING_FRAMES.size();
        image = LEFT_MONKEY_FALLING_FRAMES.at(imageIndex);
    }
    else if (side == RIGHT && isHitable)
    {
        imageIndex = (imageIndex + 1) % RIGHT_MONKEY_FRAMES.size();
        image = RIGHT_MONKEY_FRAMES.at(imageIndex);
    }
    else if (side == RIGHT && !isHitable)
    {
        imageIndex = (imageIndex + 1) % RIGHT_MONKEY_FALLING_FRAMES.size();
        image = RIGHT_MONKEY_FALLING_FRAMES.at(imageIndex);
    }

    mObs->changedFrameInModel(objId, image);
}

void Monkey::increaseCocoTime(int t)
{
    cocoTime += t;

    if (cocoTime > maxLoadTime) { cocoTime = maxLoadTime; }
}

void Monkey::setMaxLoadTime()
{
    maxLoadTime = COCO_SHOOT_INTERVAL.at(_difficulty_) +
                AI_MIN_ADD_COCO_SHOOT_INTERVAL.at(_difficulty_) + rand() %
                (AI_MAX_ADD_COCO_SHOOT_INTERVAL.at(_difficulty_) - AI_MIN_ADD_COCO_SHOOT_INTERVAL.at(_difficulty_) + 1);
}

Monkey::~Monkey()
{
    mObs->destroyedInModel(objId);
}
